/**
 * Copyright Marvell Inc
 */

package com.hisense.settings.device;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;

import com.android.settings.R;
import com.google.android.tv.mediadevices.Capabilities.Capability;
import com.google.android.tv.mediadevices.Device;
import com.google.android.tv.mediadevices.MediaDevicesIntents;
//import com.marvell.tv.TVAVSettingsConstants.TvSource;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Class for Settings NON-RF sources online and to Auto pair the same
 * @author swetha
 * @date 1-Feb-2012
 * @version 1.0
 */
public class PairingDevice {

    // Variable to store TAG message for Logging

    private static final String TAG = "PairingDeviceActivity";

    private static final String PACKAGE_NAME_PREFIX = "com.marvell.willowtv.controller.device.";

    // Video URI bound to,If Capability.IS_BOUND_TO_PORT is set
    public static final String TUNER_DEVICE_ID = PACKAGE_NAME_PREFIX + "TUNER";
    public static final String BOUND_PORT_TUNER_VIDEO_URI = "hdmi://tuner?port=8";

    // Variable to store URI for HDMI1 source
    public static final String HDMI1_DEVICE_ID = PACKAGE_NAME_PREFIX + "HDMI_1";
    public static final String BOUND_PORT_HDMI1_VIDEO_URI = "hdmi://localhost?port=1";

    // Variable to store URI for HDMI2 source
    public static final String HDMI2_DEVICE_ID = PACKAGE_NAME_PREFIX + "HDMI_2";
    public static final String BOUND_PORT_HDMI2_VIDEO_URI = "hdmi://localhost?port=2";

    // Variable to store URI for HDMI3 source
    public static final String HDMI3_DEVICE_ID = PACKAGE_NAME_PREFIX + "HDMI_3";
    public static final String BOUND_PORT_HDMI3_VIDEO_URI = "hdmi://localhost?port=3";

    // Variable to store URI for HDMI4 source
    public static final String HDMI4_DEVICE_ID = PACKAGE_NAME_PREFIX + "HDMI_4";
    public static final String BOUND_PORT_HDMI4_VIDEO_URI = "hdmi://localhost?port=4";

    // Variable to store URI for COMPONENT source
    public static final String COMPONENT_DEVICE_ID = PACKAGE_NAME_PREFIX + "COMPONENT";
    public static final String BOUND_PORT_COMPONENT_VIDEO_URI = "hdmi://localhost?port=5";

    // Variable to store URI for COMPOSITE source
    public static final String COMPOSITE_DEVICE_ID = PACKAGE_NAME_PREFIX + "COMPOSITE";
    public static final String BOUND_PORT_COMPOSITE_VIDEO_URI = "hdmi://localhost?port=6";

    // Variable to store URI for VGA source
    public static final String VGA_DEVICE_ID = PACKAGE_NAME_PREFIX + "VGA";
    public static final String BOUND_PORT_VGA_VIDEO_URI = "hdmi://localhost?port=7";

    @SuppressWarnings("serial")
    public static final Map<String, Object> DeviceIdSourceMap = new HashMap<String, Object>() {
        {
            /*put(TUNER_DEVICE_ID, TvSource.TV_SourceDtv);
            put(COMPONENT_DEVICE_ID, TvSource.TV_SourceComponent);
            put(COMPOSITE_DEVICE_ID, TvSource.TV_SourceCvbs0);
            put(HDMI1_DEVICE_ID, TvSource.TV_SourceHdmi0);
            put(HDMI2_DEVICE_ID, TvSource.TV_SourceHdmi1);
            put(HDMI3_DEVICE_ID, TvSource.TV_SourceHdmi2);
            put(HDMI4_DEVICE_ID, TvSource.TV_SourceHdmi3);
            put(VGA_DEVICE_ID, TvSource.TV_SourceVga);*/
        }
    };

    @SuppressWarnings("serial")
    public static final Map<String, String> DeviceIdUriMap = new HashMap<String, String>() {
        {
            put(TUNER_DEVICE_ID, BOUND_PORT_TUNER_VIDEO_URI);
            put(COMPONENT_DEVICE_ID, BOUND_PORT_COMPONENT_VIDEO_URI);
            put(COMPOSITE_DEVICE_ID, BOUND_PORT_COMPOSITE_VIDEO_URI);
            put(HDMI1_DEVICE_ID, BOUND_PORT_HDMI1_VIDEO_URI);
            put(HDMI2_DEVICE_ID, BOUND_PORT_HDMI2_VIDEO_URI);
            put(HDMI3_DEVICE_ID, BOUND_PORT_HDMI3_VIDEO_URI);
            put(HDMI4_DEVICE_ID, BOUND_PORT_HDMI4_VIDEO_URI);
            put(VGA_DEVICE_ID, BOUND_PORT_VGA_VIDEO_URI);
        }
    };

    @SuppressWarnings("serial")
    public static List<String> DevIdOrderList = new ArrayList<String>() {
        {
            add(PairingDevice.TUNER_DEVICE_ID);
            add(PairingDevice.COMPOSITE_DEVICE_ID);
            add(PairingDevice.COMPONENT_DEVICE_ID);
            add(PairingDevice.HDMI1_DEVICE_ID);
            add(PairingDevice.HDMI2_DEVICE_ID);
            add(PairingDevice.HDMI3_DEVICE_ID);
            add(PairingDevice.HDMI4_DEVICE_ID);
            add(PairingDevice.VGA_DEVICE_ID);
        }
    };

    public class DeviceComparator implements Comparator<Object> {
        @Override
        public int compare(Object arg0, Object arg1) {
            Device dev1 = (Device) arg0;
            Device dev2 = (Device) arg1;
            int dev1pos = DevIdOrderList.indexOf(dev1.getId());
            int dev2pos = DevIdOrderList.indexOf(dev2.getId());
            return dev1pos - dev2pos;
        }
    }

    // Variable to decide whether to auto pair NON-RF sources
    private boolean pairAllDevices;

    public static String getDeviceNameBySource(final Context context, int sourceId) {
        String[] deviceNameArray = context.getResources().getStringArray(R.array.device);
        String deviceName = "";
        /*if (sourceId == TvSource.TV_SourceAtv.value()
                || sourceId == TvSource.TV_SourceDtv.value()) {
            deviceName = deviceNameArray[0];
        } else if (sourceId == TvSource.TV_SourceHdmi0.value()) {
            deviceName = deviceNameArray[1];
        } else if (sourceId == TvSource.TV_SourceHdmi1.value()) {
            deviceName = deviceNameArray[2];
        } else if (sourceId == TvSource.TV_SourceHdmi2.value()) {
            deviceName = deviceNameArray[3];
        } else if (sourceId == TvSource.TV_SourceHdmi3.value()) {
            deviceName = deviceNameArray[4];
        } else if (sourceId == TvSource.TV_SourceComponent.value()) {
            deviceName = deviceNameArray[5];
        } else if (sourceId == TvSource.TV_SourceCvbs0.value()) {
            deviceName = deviceNameArray[6];
        } else if (sourceId == TvSource.TV_SourceVga.value()) {
            deviceName = deviceNameArray[7];
        }*/
        return deviceName;
    }

    public static int getPortId(final String deviceId) {
        Uri uri = Uri.parse(PairingDevice.DeviceIdUriMap.get(deviceId));
        String portId = uri.getQueryParameter("port");
        Integer iport = Integer.parseInt(portId);
        return iport;
    }

    public static int getDevIndexById(final List<Device> deviceList, final String deviceId) {
        int index = 0;
        for (Device iDevice : deviceList) {
            if (deviceId != null && deviceId.equals(iDevice.getId()))
                return index;

            index++;
        }

        return -1;
    }

    public static List<Device> filterDeviceList(final Context context,
            final List<Device> deviceList,
            boolean filterExternalPackage, Set<String> excludeDeviceIdSet) {
        List<Device> filterDevices = new ArrayList<Device>();
        String pkgName = context.getPackageName();

        for (Device iDevice : deviceList) {
            if (filterExternalPackage && !pkgName.equals(iDevice.getPackageName()))
                continue;

            if (excludeDeviceIdSet != null && excludeDeviceIdSet.contains(iDevice.getId()))
                continue;

            filterDevices.add(iDevice);
        }

        return filterDevices;
    }

    /**
     * Method to set all Non-RF devices online and auto pair all devies.
     * @param context
     *            Context instance
     * @param pairDevices
     *            true - Auto pair all Non-RF devices
     */
    public void pairDevices(final Context context, final boolean pairDevices) {
        Log.d(TAG, "pairDevices ()");
        pairAllDevices = pairDevices;

        String[] deviceNameArray = context.getResources().getStringArray(R.array.device);
        pairNonRFInputDevices(deviceNameArray[1], HDMI1_DEVICE_ID, BOUND_PORT_HDMI1_VIDEO_URI,
                context);
        pairNonRFInputDevices(deviceNameArray[2], HDMI2_DEVICE_ID, BOUND_PORT_HDMI2_VIDEO_URI,
                context);
        pairNonRFInputDevices(deviceNameArray[3], HDMI3_DEVICE_ID, BOUND_PORT_HDMI3_VIDEO_URI,
                context);
        pairNonRFInputDevices(deviceNameArray[4], HDMI4_DEVICE_ID, BOUND_PORT_HDMI4_VIDEO_URI,
                context);
        pairNonRFInputDevices(deviceNameArray[5], COMPONENT_DEVICE_ID,
                BOUND_PORT_COMPONENT_VIDEO_URI, context);
        pairNonRFInputDevices(deviceNameArray[6], COMPOSITE_DEVICE_ID,
                BOUND_PORT_COMPOSITE_VIDEO_URI, context);
        pairNonRFInputDevices(deviceNameArray[7], VGA_DEVICE_ID, BOUND_PORT_VGA_VIDEO_URI, context);
    }

    /**
     * Creates the Device instance and calls online().
     * @param deviceName
     *            - Name of the Device
     * @param deviceId
     *            - Device Id
     * @param videoURI
     *            - URI associated with it
     * @param context
     *            - application context
     */
    private void pairNonRFInputDevices(final String deviceName, final String deviceId,
            final String videoURI,
            final Context context) {

        /*
         * final Device device = new Device(context.getPackageName(), deviceId,
         * deviceName, Device.NO_SUMMARY, Device.NO_MANUFACTURER,
         * Device.NO_MODEL, true);
         */
        final Device device = new Device.Builder(context.getPackageName(), deviceId)
                .setSummary(Device.NO_SUMMARY)
                .setManufacturer(Device.NO_MANUFACTURER)
                .setCapability(Capability.USES_CHANNEL_LINEUP, false)
                .setCapability(Capability.IS_PASSTHROUGH_ONLY, true)
                .setCapability(Capability.CAN_BE_DEFAULT, true)
                .setCapability(Capability.IS_BOUND_TO_PORT, true)
                .setCapability(Capability.IS_BOUND_TO_PORT, videoURI)
                .setLabel(deviceName)
                .build();

        /*
         * device.setCapability(Capability.HAS_CHANNEL_LINEUP, false);
         * device.setCapability(Capability.IS_PASSTHROUGH_ONLY, true);
         * device.setCapability(Capability.CAN_BE_DEFAULT, true);
         * device.setCapability(Capability.IS_BOUND_TO_PORT, true);
         * device.setCapabilityExtra(Capability.IS_BOUND_TO_PORT, videoURI);
         */

        // Below Code enables Auto Pairing
        if (pairAllDevices) {
            final Intent pairingIntent = MediaDevicesIntents.createServicePairIntent(device,
                    Uri.parse(videoURI));
            context.startService(pairingIntent);
            Log.d(TAG,
                    "************* Paired All Devices : " + context.getPackageName());
        }
        Device.online(context, device);
    }
}
